package org.inspursc.s0517.health.common.config;

import org.inspursc.s0517.health.common.security.CustomUserService;
import org.inspursc.s0517.health.common.security.MyAccessDeniedHandler;
import org.inspursc.s0517.health.common.security.MyAuthenticationProcessingFilterEntryPoint;
import org.inspursc.s0517.health.common.security.MyFilterSecurityInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.session.HttpSessionEventPublisher;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${uploadPath}")
    private String uploadPath;

    @Autowired
    private MyFilterSecurityInterceptor myFilterSecurityInterceptor;

    @Autowired
    private SessionRegistry sessionRegistry;

    @Autowired
    private MyAccessDeniedHandler myAccessDeniedHandler;

    @Autowired
    private MyAuthenticationProcessingFilterEntryPoint authenticationProcessingFilterEntryPoint;

    /**
     * 自定义UserDetailsService，从数据库中读取用户信息
     *
     * @return
     */
    @Bean
    UserDetailsService customUserService() { //注册UserDetailsService 的bean
        return new CustomUserService();
    }

    /**
     * user Details Service验证
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserService()).passwordEncoder(passwordEncoder());

    }

    @Override
    public void configure(WebSecurity web) {
        web.ignoring().antMatchers("/lib/**","/static/**","/resource/**","/"+uploadPath+"logo/**");
        web.ignoring().antMatchers("/share/**");
        web.ignoring().antMatchers("/login", "/login.html","/checkIsLogin","/organization/getByDomainName");
        web.ignoring().antMatchers("/swagger-ui.html", "/webjars/**", "/swagger-resources", "/v2/api-docs", "/configuration/**", "/null/swagger-resources/configuration/ui");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.exceptionHandling().accessDeniedHandler(myAccessDeniedHandler).authenticationEntryPoint(authenticationProcessingFilterEntryPoint);
       //跨站防护登录关
        http.csrf().disable();
        http.authorizeRequests()
                //避开权限验证代码
//                .antMatchers("/*").permitAll();
                .anyRequest().authenticated();
        http.sessionManagement().invalidSessionUrl("/").sessionFixation().none().maximumSessions(1).expiredUrl("/").maxSessionsPreventsLogin(true).sessionRegistry(sessionRegistry);
        http.logout().logoutUrl("/logout").logoutSuccessUrl("/").invalidateHttpSession(true).deleteCookies("JSESSIONID").permitAll()
                .and().rememberMe().tokenValiditySeconds(7 * 24 * 60 * 60).key("token_key")
                .and().httpBasic();
        http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class);
    }

    /**
     * 设置用户密码的加密方式为MD5加密
     *
     * @return
     */
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {

        return new BCryptPasswordEncoder();
    }

    @Bean
    public SessionRegistry getSessionRegistry() {
        SessionRegistry sessionRegistry = new SessionRegistryImpl();
        return sessionRegistry;
    }

    @Bean
    public ServletListenerRegistrationBean httpSessionEventPublisher() {
        return new ServletListenerRegistrationBean(new HttpSessionEventPublisher());
    }
}
